/**
  ******************************************************************************
  * @file    User/LL/user.c
  * @author  TOPSYS Application Team
  * @version V1.0.0
  * @date    02-11-2018
  * @brief   Main program body
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; COPYRIGHT 2018 TOPSYS</center></h2>
  *
  *
  ******************************************************************************
  */

/* Includes ------------------------------------------------------------------*/
#include "include.h"
#include "stdlib.h"
#include "TM1668.h"
#include "user.h"
#include "TkLib.h"
#include "ts32fx_irq.h"
#include "Vm.h"
//#include "vardefine.h"

/** @addtogroup Template_Project
  * @{
  */

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Public variables ---------------------------------------------------------*/

/* The touchkey multiplexing digital tube works in automatic scanning mode, which requires 45 words as the computing space */
const u16 time_disp_tab[] = {DISP0, DISP1, DISP2, DISP3, DISP4, DISP5, DISP6, DISP7, DISP8, DISP9};
static u32 cur_tick_cnt = 0;
static u32 second_disp = 0;
static bool buz_begin = false;
static u32 buz_cur_tick = 0;
static u32 tk_value_pre = 0;
static u32 tk_value = 0;
static u32 tk_value_old = 0;
static u32 tk_value_backup = 0;
u32 timer_irq_count = 0;
#define PEROID 10;
int timer_period = 0;
int timer_motor = 0;
int counter = 0;
TYPE_LL_TIMER_CNT_CFG cnt_cfg;

/*sw var for CS*/
u32 sw_db_cnt = 0;
u32 sw_db_sta_bk = 0;

/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/

#define UART_BAUDRATE LL_UARTx_BAUDRATE

/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Public variables ---------------------------------------------------------*/

#define BUZ_TIMER TIMER2
#define BUZ_GPIO GPIOA
#define BUZ_PIN LL_GPIO_PIN_0
#define IIC_GPIO GPIOC
#define IIC_DIO 1
#define IIC_CLK 2
#define IIC_STB 0
#define TM1668_TIMER TIMER1
#define SPUSE SPI0
#define BUZ_TIME 150

int VmExecRes = 0;
#define MAX_DISP NBYTES
unsigned char DispLEDNum[MAX_DISP] = {0x6D, 0x6D, 0x6D, 0x6D, 0x6D, 0x6D, 0x6D};

TYPE_LL_TIMER_PWM_CFG pwm_cfg;

//
void buz_config(TIMER_TypeDef *Timer, GPIO_TypeDef *GpioSel, uint16_t PinSel)
{
  TYPE_LL_GPIO_INIT gpio_init_cfg;

  TYPE_LL_TIMER_INIT timer_init;
  memset(&gpio_init_cfg, 0x00, sizeof(gpio_init_cfg));

	#if 1
  gpio_init_cfg.gpio_mode = LL_GPIO_MODE_AF;
  gpio_init_cfg.gpio_pin = PinSel;   
	ll_gpio_init(GpioSel, &gpio_init_cfg);
  ll_gpio_pin_af_config(GpioSel, LL_GPIO_PIN_SOURCE_0, LL_GPIO_AF_1);

	#else
  TYPE_LL_GPIO_INIT gpio_struct;
  memset(&gpio_struct, 0x00, sizeof(gpio_struct));
  gpio_struct.gpio_pin = LL_GPIO_PIN_1;
  gpio_struct.gpio_mode = LL_GPIO_MODE_AF;
  // gpio_struct.gpio_speed_mode = LL_GPIO_SPEED_MODE_V;
  // gpio_struct.gpio_speed_level = LL_GPIO_SPEED_LEVEL_7;
  ll_gpio_init(GPIOC, &gpio_struct);
  ll_gpio_pin_af_config(GPIOC, LL_GPIO_PIN_SOURCE_1, LL_GPIO_AF_1);
	#endif

  timer_init.timer_src_sel = LL_TIMER_SRC_SYS_RISING;
  timer_init.prescaler = LL_TIMER_PSC_128;
  ll_timer_init(Timer, &timer_init);

  pwm_cfg.pwm_duty = 0x1;
  pwm_cfg.pwm_period = 0x64;
  ll_timer_pwm_mode_config(Timer, &pwm_cfg);
}

void motor_config(GPIO_TypeDef *GpioSel, uint16_t PinSel)
{

}

void iic_init(void)
{
	
	// 7 8 9
	// 3 1 2
	// 8 9 7
  NVIC_InitTypeDef nvic;
  nvic.NVIC_IRQChannel = TIM1_IRQn;
  nvic.NVIC_IRQChannelPriority = 1;
  nvic.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&nvic);

  TYPE_LL_GPIO_INIT gpio_struct;
  memset(&gpio_struct, 0x00, sizeof(gpio_struct));

  gpio_struct.gpio_pin = (1<<IIC_DIO) | (1<<IIC_CLK) | (1<<IIC_STB);
//	| LL_GPIO_PIN_1 | LL_GPIO_PIN_2;

  gpio_struct.gpio_mode = LL_GPIO_MODE_OUT;
  gpio_struct.gpio_speed_mode = LL_GPIO_SPEED_MODE_V;
  gpio_struct.gpio_speed_level = LL_GPIO_SPEED_LEVEL_7;
  ll_gpio_init(IIC_GPIO, &gpio_struct);


  ll_gpio_reset_bits(IIC_GPIO, (1<<IIC_DIO));
  ll_gpio_reset_bits(IIC_GPIO, 1<<IIC_CLK);
  ll_gpio_reset_bits(IIC_GPIO, (1<<IIC_STB));


  TYPE_LL_TIMER_INIT p_init;
  TYPE_LL_TIMER_CNT_CFG cnt_cfg;

  //p_init.prescaler = LL_TIMER_PSC_NONE;
  p_init.prescaler = LL_TIMER_PSC_32;
  p_init.timer_src_sel = LL_TIMER_SRC_SYS_RISING;
  ll_timer_init(TIMER1, &p_init);

  cnt_cfg.count_initial = 0;
  cnt_cfg.count_period = 0xFF;
  cnt_cfg.count_ie = ENABLE;
  ll_timer_cnt_mode_config(TIMER1, &cnt_cfg);

  ll_timer_start(TIMER1, LL_TIMER_MODE_SEL_COUNTER);
}

/**
  * @brief  Uart initialization function
  * @param  None
  * @retval None
  */
void uart_init(void)
{
  TYPE_LL_GPIO_INIT gpio_struct;
  /* UART configuration structure variable            */
  TYPE_LL_UART_INIT uart_cfg;

  memset(&gpio_struct, 0x00, sizeof(gpio_struct));
  /* Initialize the relevant variables of the UART    */
  memset(&uart_cfg, 0x0, sizeof(uart_cfg));

  /* pc1 func0   rx   fpga:h21 pc0 func0   tx   fpga:f22 */
  gpio_struct.gpio_pin = LL_GPIO_PIN_0;
  gpio_struct.gpio_mode = LL_GPIO_MODE_AF;
  ll_gpio_init(GPIOC, &gpio_struct);
  ll_gpio_pin_af_config(GPIOC, LL_GPIO_PIN_SOURCE_0, LL_GPIO_AF_0);
  /* Configure UART baud rate to UART_BAUDRATE        */
  uart_cfg.baudrate = LL_UARTx_BAUDRATE_115200;
  uart_cfg.bit_width_sel = LL_UART_WORD_LENGTH_8B;
  uart_cfg.parity = LL_UART_PARITY_NO;
  uart_cfg.stop_bit_sel = LL_UART_STOP_1B;
  /* Call the UART driver configuration function      */
  ll_uart_init(UART1, &uart_cfg);
  debug_select_interface_set(DEBUG_UART1);
  ll_uart_enable(UART1);
  delay_ms(1);
}

/**
  * @brief  tk no reuse pins initialization function
  * @param  None
  * @retval None
  */
void tk_no_reuse_pins_init(void)
{
  /* =====================================*/
  /*     single TK IO output low voltage  */
  /* =====================================*/
  /* tochekey PA8��PA9��PA10��PA11   mode:output low*/
  TYPE_LL_GPIO_INIT gpio_struct;
  memset(&gpio_struct, 0x0, sizeof(gpio_struct));
  gpio_struct.gpio_pin = LL_GPIO_PIN_8 | LL_GPIO_PIN_9 | LL_GPIO_PIN_10 | LL_GPIO_PIN_11;
  gpio_struct.gpio_mode = LL_GPIO_MODE_OUT;
  gpio_struct.gpio_speed_mode = LL_GPIO_SPEED_MODE_V;
  gpio_struct.gpio_speed_level = LL_GPIO_SPEED_LEVEL_7;
  ll_gpio_init(GPIOA, &gpio_struct);
  ll_gpio_reset_bits(GPIOA, gpio_struct.gpio_pin);
  /* tochekey PB0   mode:output low*/
  gpio_struct.gpio_pin = LL_GPIO_PIN_0;
  ll_gpio_init(GPIOB, &gpio_struct);
  ll_gpio_reset_bits(GPIOB, gpio_struct.gpio_pin);
}

void init_VirtualMachine(void)
{

}

/**
  * @brief  TK initialization function
  * @param  None
  * @retval None
  */

void setIO(char p, short v)
{
  ll_gpio_set_bits(IIC_GPIO, v);
}

void resetIO(char p, short v)
{
  ll_gpio_reset_bits(IIC_GPIO, v);
}

int tk_init(void)
{
  tk_sw_alg_init();
  buz_config(BUZ_TIMER, BUZ_GPIO, BUZ_PIN);
  motor_config(GPIOC, LL_GPIO_PIN_1);
  iic_init();
  init_VirtualMachine();
  funPtr.setGPIO = setIO;
  funPtr.resetGPIO = resetIO;
	TM1668_VmInit(NBYTES, IIC_DIO, IIC_CLK, IIC_STB, GPIOA_PORT,GPIOA_PORT,GPIOA_PORT);
  return 1;
}

/**
  * @brief  TK data handle function
  * @param  None
  * @retval None
  */

bool DisplayPerS = true;
short DispValue = 0x0;
void tk_handle(void)
{
//ll_gpio_reset_bits(GPIOC, 1<<1);
//	ll_gpio_reset_bits(GPIOC, 1<<2);
//	ll_gpio_reset_bits(GPIOC, 1<<0);
//	delay_ms(800);
///ll_gpio_set_bits(GPIOC, 1<<1);//？dio
//	ll_gpio_set_bits(GPIOC, 1<<2);//dio
//	ll_gpio_set_bits(GPIOC, 1<<0);//7
    u8 bright = 0, value = 1;
    int pre_timer_irq_count = timer_irq_count;
    buz_start();
    u32 ctick = GetSysTick();
    u32 ptick = ctick;
    while (1 != 0)
    {
      ctick = GetSysTick();
      if ( 1 && (timer_irq_count-pre_timer_irq_count) > 0)
      {	
        pre_timer_irq_count = timer_irq_count = 0;
				
        if (-1 != VmIndex())
        {
          VmNext();
        }else if((ctick - ptick) > 1000){
          ptick = ctick;
					DispValue++;
          short s = DispValue % 1000;
          for (int i = 0; i < MAX_DISP / 2; i++)
          {
            short digit = s % 10;
            s = s / 10;
            short dDispValue = code_DEG_TAB_UC[digit];
            DispLEDNum[i * 2] = 0x0;// (dDispValue & 0xFF);
            DispLEDNum[i * 2 + 1] = 0x0;//((dDispValue >> 8) & 0xFF);
          }
					//NBYTES
          TM1668_VmDispSeg(DispLEDNum,0,DispValue%8+1);
          
        }
				

      }

      //state machine

      ll_wdt_feed(WDT);
			
			continue;

      tk_sw_alg_excute();

      tk_value = tk_sw_alg_key_map_get(TK);

      if (tk_value != tk_value_old)
      {
        if (tk_value)
        {

          switch (tk_value)
          {
          case (1 << 12):
            ll_timer_pwm_mode_config(BUZ_TIMER, &pwm_cfg);

            ptick = ctick - 1000;
            DisplayPerS = false;
            DispValue = 0;
            
            break;
          case (1 << 13):
            //timer_period = timer_period + 0x1;
            //if(timer_period > 9) timer_period = 10;

            pwm_cfg.pwm_duty += 3;
            if (pwm_cfg.pwm_duty > 0x64)
            {
              pwm_cfg.pwm_duty = 0x64;
            }
            ll_timer_pwm_mode_config(BUZ_TIMER, &pwm_cfg);

            ptick = ctick - 1000;
            DisplayPerS = false;
            DispValue = 220;
            break;
          case (1 << 14):
            break;
          case (1 << 16):
            break;
          case (1 << 17):
            break;
          case (1 << 4):
            break;
          case (1 << 5):
            break;
          default:
            break;
          }
        }
        else
        {
          DisplayPerS = true;
        }
      }
      tk_value_old = tk_value;
      //buz_chk_stop();
    }
  }

  /**
  * @brief  buz_start config  
  * @param  None
  * @retval None
  */
  void buz_start(void)
  {
    ll_timer_start(BUZ_TIMER, LL_TIMER_MODE_SEL_PWM);
    buz_cur_tick = GetSysTick();
    buz_begin = true;
  }

  /**
  * @brief  if buz stop check according to buz open timeout  
  * @param  None
  * @retval None
  */
  void buz_chk_stop(void)
  {
    if ((true == buz_begin) && (is_systick_expired(buz_cur_tick, BUZ_TIME)))
    {
      ll_timer_stop(BUZ_TIMER);
      buz_begin = false;
    }
  }

  /**
  * @}
  */

  /*************************** (C) COPYRIGHT 2018 TOPSYS ***** END OF FILE *****/
